package cc.itez.wx.linkman.service.impl;

import cc.itez.wx.linkman.service.RoleService;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cc.itez.wx.linkman.val.Role;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private Gson gson;
    private final Map<Role, Set<String>> roleUsers = new HashMap<>();

    private File permissionsFile;

    @Value("${wx.permission.super-admin-password}")
    private String superAdminPassword;

    @Value("${wx.permission.file}")
    public void setPermissionsFile(String filepath) {
        this.permissionsFile = new File(filepath);
        if (this.permissionsFile.exists()) {
            try (FileReader reader = new FileReader(this.permissionsFile, StandardCharsets.UTF_8)) {
                JsonElement document = JsonParser.parseReader(reader);
                if (document.isJsonObject()) {
                    JsonObject object = document.getAsJsonObject();
                    for (String roleUuid : object.keySet()) {
                        document = object.get(roleUuid);
                        if (document != null && document.isJsonArray()) {
                            Role role = Role.of(roleUuid);
                            if (role != null) {
                                Set<String> users = this.roleUsers.computeIfAbsent(role, key -> new HashSet<>());
                                for (JsonElement element : document.getAsJsonArray()) {
                                    if (element.isJsonPrimitive()) {
                                        users.add(element.getAsString());
                                    }
                                }
                            }
                        }
                    }
                    return;
                }
            } catch (IOException e) {
            }
            // 如果权限文件内容不符合格式要求，则复制错误文件，源删除重建
            FileUtil.copy(this.permissionsFile, new File(StrUtil.format("{}.{}.error", this.permissionsFile.getAbsolutePath(), System.currentTimeMillis() / 1000)), true);
            FileUtil.del(this.permissionsFile);
        }
        // 创建权限文件
        FileUtil.touch(this.permissionsFile);
    }

    /**
     * 添加用户
     *
     * @param role   角色
     * @param openId 微信OpenId
     */
    @Override
    public void addUser(Role role, String openId) {
        this.roleUsers.computeIfAbsent(role, (key) -> new HashSet<>()).add(openId);
        FileUtil.writeString(gson.toJson(role), this.permissionsFile, StandardCharsets.UTF_8);
    }

    /**
     * 根据用户OpenId查询其角色
     *
     * @param openId 微信OpenId
     */
    @Override
    public Set<Role> getUserRoles(String openId) {
        Set<Role> roles = new HashSet<>();
        this.roleUsers.forEach((role, users) -> {
            if (users.contains(openId)) {
                roles.add(role);
            }
        });
        return roles;
    }
}
